package com.qing.springbootdispatcherservice.mq;

import com.alibaba.fastjson.JSONObject;

import com.qing.springbootdispatcherservice.pojo.Order;
import com.qing.springbootdispatcherservice.service.DispatchService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Service;

import java.io.IOException;


@Service
public class OrderMQConsumer {


	@Autowired
	private DispatchService dispatchService;


	private int count=1;

	//解决消息重试的集中方案：

	/**
	 *
	 * 1: 控制重发的次数
	 * 2： try+catch+手动ack
	 * 3：try+catch+手动ack+死信队列处理
	 */
	@RabbitListener(queues = "order.queue")
	public void messageConsumer(String orderMsg,
								Channel channel,
								CorrelationData correlationData,
								@Header(AmqpHeaders.DELIVERY_TAG) long tag
								) throws IOException {

		try {
			//		1.获取消息队列的消息
			System.out.println("收到Mq的消息是："+orderMsg+", count="+count++);
			Order order= JSONObject.parseObject(orderMsg,Order.class);

			String orderId=order.getOrderId();
			//2. 派单处理
			System.out.println(1/0); //出现异常
			dispatchService.dispatch(orderId);
			//3. 手动ack告诉mq消息已经正常消费
			channel.basicAck(tag,false);
		} catch (Exception ex) {

				//如果出现异常的情况下，根据实际的情况去进行重发
				//重发一次后，丢失，还是日记，存库根据自己的业务场景去决定


					/**
					 *拒绝一条或多条收到的消息。
					 *
					 *@param deliveryTag从收到的中标记
					 *@param multiple false 多条处理
					 *@param requeue  重发  false 不会重发，会把消息打入私信队列
					 *                true 的会死循环的重发，建议 如果使用true的话，不要加try/catch 否则会造成死循环
					 *
					 */
				channel.basicNack(tag, false, false);

				System.out.println("异常信息:"+ex);

		}

	}
}
